<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>充电宝租借系统 - 柜机管理</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js"></script>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/qrcode/build/qrcode.min.js"></script>
    <style>
        * { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Microsoft YaHei', sans-serif; }
        body { background-color: #f5f7fa; color: #333; padding: 20px; }
        .container { max-width: 1200px; margin: 0 auto; background: white; border-radius: 12px; box-shadow: 0 4px 20px rgba(0,0,0,0.1); overflow: hidden; }
        .header { background: linear-gradient(135deg, #3498db, #2c3e50); color: white; padding: 20px; text-align: center; }
        .header h1 { margin-bottom: 10px; font-size: 24px; }
        .status-bar { display: flex; justify-content: space-between; background: #f1f2f6; padding: 10px 20px; font-size: 14px; }
        .status-connected { color: #2ecc71; font-weight: bold; }
        .status-disconnected { color: #e74c3c; font-weight: bold; }
        .device-selector { padding: 15px 20px; background: #eaf6ff; border-bottom: 1px solid #ddd; }
        .device-selector select { padding: 8px 15px; border-radius: 4px; border: 1px solid #ccc; width: 200px; }
        .main-content { padding: 20px; display: grid; grid-template-columns: 3fr 1fr; gap: 20px; }
        @media (max-width: 968px) { .main-content { grid-template-columns: 1fr; } }
        .slots-container { display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px; }
        .slot { background: #ecf0f1; border-radius: 8px; padding: 15px 10px; text-align: center; transition: all 0.3s ease; cursor: pointer; min-height: 120px; display: flex; flex-direction: column; justify-content: center; align-items: center; }
        .slot.available { background: #d5f5e3; border: 2px solid #2ecc71; }
        .slot.occupied { background: #fadbd8; border: 2px solid #e74c3c; }
        .slot.empty { background: #f2f3f4; border: 2px dashed #bdc3c7; cursor: not-allowed; }
        .slot-id { font-weight: bold; margin-bottom: 8px; font-size: 16px; }
        .slot-status { font-size: 14px; padding: 4px 8px; border-radius: 4px; margin-top: 8px; }
        .action-panel { background: #f8f9fa; border-radius: 8px; padding: 20px; display: flex; flex-direction: column; gap: 15px; }
        .action-btn { padding: 12px; border: none; border-radius: 6px; font-weight: bold; cursor: pointer; transition: all 0.2s ease; }
        .action-btn.report { background: #f39c12; color: white; }
        .action-btn.report:hover { background: #e67e22; }
        .action-btn.scan { background: #3498db; color: white; }
        .action-btn.scan:hover { background: #2980b9; }
        .device-info { text-align: center; padding: 10px; }
        .device-info img { max-width: 100px; margin-top: 10px; }
        .log-container { padding: 20px; border-top: 1px solid #eee; }
        .log-container h3 { margin-bottom: 10px; color: #2c3e50; }
        #content { width: 100%; height: 200px; padding: 12px; border: 1px solid #ddd; border-radius: 6px; background: #f8f9fa; font-family: monospace; font-size: 14px; resize: vertical; }
    </style>
</head>
<body>
<div class="container">
    <div class="header">
        <h1>充电宝租借系统</h1>
        <p>多柜机管理系统</p>
    </div>

    <div class="status-bar">
        <div>状态: <span id="connection-status" class="status-disconnected">未连接</span></div>
        <div>时间: <span id="current-time"></span></div>
    </div>

    <div class="device-selector">
        <label for="device-select">选择柜机: </label>
        <select id="device-select"></select>
    </div>

    <div class="main-content">
        <div>
            <div class="slots-container"></div>
        </div>
        <div class="action-panel">
            <!-- <button class="action-btn report" id="report-property">上报属性测试</button> -->
            <button class="action-btn scan" id="simulate-scan">模拟扫码租借</button>
            <div class="device-info">
                <p>设备编号: <span id="device-id"></span></p>
                <p>设备名称: <span id="device-name"></span></p>
                <img id="device-qr" src="" alt="设备二维码">
                <p>扫描二维码租借充电宝</p>
            </div>
        </div>
    </div>

    <div class="log-container">
        <h3>操作日志</h3>
        <textarea id="content" readonly></textarea>
    </div>
</div>

<script>
$(function() {
    let currentCabinet = null;
    let client = null;

    /** 初始化设备下拉框 */
    function initDeviceSelector() {
        $.get("http://localhost:18080/device/cabinet/devices", function(res) {
            if (!res || res.code !== 200) {
                logMessage("❌ 加载柜机列表失败");
                return;
            }

            const devices = res.data;
            const selector = $('#device-select');
            selector.empty();

            devices.forEach(d => {
                selector.append(`<option value="${d.id}">${d.name} (${d.cabinetNo})</option>`);
            });

            if (devices.length > 0) {
                currentCabinet = devices[0];
                loadDeviceData(currentCabinet.id);
                connectMQTT();
            }

            selector.change(function() {
                const id = $(this).val();
                currentCabinet = devices.find(d => d.id == id);
                if (client && client.isConnected()) client.disconnect();
                loadDeviceData(id);
                connectMQTT();
            });
        });
    }

    /** 加载柜机信息 */
    function loadDeviceData(cabinetId) {
        $.get(`http://localhost:18080/device/cabinet/devices/${cabinetId}`, function(res) {
            if (!res || res.code !== 200) {
                logMessage("❌ 加载柜机数据失败");
                return;
            }
            const data = res.data;
            console.log("loadDeviceData函数中，data为：", data)
            $('#device-id').text(data.id);
            $('#device-name').text(data.name);
            // 更新槽位数据到 currentCabinet
            currentCabinet.slots = data.slots || [];
            renderSlots(data.slots || []);
        });
    }

    /** 渲染槽位 */
    // ✅ 修正：兼容不同字段名的slot对象
    function renderSlots(slots) {
        const container = $('.slots-container');
        container.empty();

        slots.forEach(slot => {
            const slotNo = slot.slotNo || slot.id || slot.no || slot.code || '?';
            console.log("renderSlot函数中，slot.status为：", slot.status)
            const status = slot.status; // available-空闲 occupied-占用 empty-锁定
            const powerBankId = slot.powerBankId || slot.powerbankId || null;

            const statusText = status === 'occupied' ? '已占用' :
                               status === 'available' ? '可用' : '锁定';

            const div = $(`
                <div class="slot ${status}" data-slot="${slotNo}" data-status="${status}">
                    <div class="slot-id">槽位 ${slotNo}</div>
                    <div class="slot-status">${statusText}</div>
                </div>
            `);

            if (status !== 'empty') {
                div.click(() => toggleSlot(slotNo, status));
            }
            container.append(div);
        });
        updateQRCode();
    }

    /** 切换槽位状态 */
    function toggleSlot(slotNo, status) {
        console.log(`切换槽位${slotNo}状态为${status}`);
        const action = status === '0' ? 'return' : 'rent';
        $.ajax({
            url: `http://localhost:18080/device/cabinet/devices/${currentCabinet.id}/slots/${slotNo}/status`,
            type: 'POST',
            contentType: 'application/json',
            data: JSON.stringify({ action }),
            success: res => {
                if (res && res.code === 200) {
                    logMessage(`✅ 槽位${slotNo}状态更新成功`);
                    renderSlots(res.data.slots);
                } else {
                    logMessage("❌ 更新槽位状态失败");
                }
            }
        });
    }

    /** MQTT连接 */
    function connectMQTT() {
        if (!currentCabinet) return;
        const hostname = '192.168.200.130';
        const port = 8083;
        const clientId = currentCabinet.clientId || `cabinet_${currentCabinet.id}_${Math.random().toString(36).slice(2,8)}`;
        const topic = `/sys/scan/submit/${currentCabinet.id}`;

        logMessage(`🔌 准备连接 MQTT (${clientId})`);
        client = new Paho.MQTT.Client(hostname, port, clientId);

        const options = {
            timeout: 5,
            keepAliveInterval: 60,
            cleanSession: true,
            onSuccess: function() {
                logMessage("✅ MQTT连接成功");
                $('#connection-status').removeClass('status-disconnected').addClass('status-connected').text('已连接');
                client.subscribe(topic);
                logMessage("📡 已订阅主题：" + topic);
            },
            onFailure: e => {
                logMessage("❌ MQTT连接失败: " + e.errorMessage);
            }
        };

        client.onConnectionLost = function(resp) {
            if (resp.errorCode !== 0) {
                logMessage("⚠️ 连接断开: " + resp.errorMessage);
                $('#connection-status').removeClass('status-connected').addClass('status-disconnected').text('未连接');
            }
        };

        client.onMessageArrived = function(msg) {
            logMessage("📩 收到消息: " + msg.payloadString);
        };

        client.connect(options);
    }

    function generateRandomStr() {
        const min = 10000000, max = 99999999;
        return 'mq' + (Math.floor(Math.random()*(max-min+1))+min).toString();
    }

    function send(topic, message) {
        if (!client || !client.isConnected()) { logMessage("❌ MQTT连接未就绪"); return; }
        const msg = new Paho.MQTT.Message(message);
        msg.destinationName = topic;
        client.send(msg);
        logMessage("发送消息到 " + topic + ": " + message);
    }

    // 上报属性测试
    $('#report-property').click(function() {
        const slots = $('.slot.occupied');
        if (slots.length > 0) {
            const slot = $(slots[0]);
            const mNo = generateRandomStr();
            const message = `mNo=${mNo}|cNo=${currentCabinet.id}|pNo=${slot.data('slot')}|sNo=1|ety=100`;
            send("/sys/property/post", message);
        } else { alert('当前没有已占用的充电宝，无法上报属性'); }
    });

    // 模拟扫码租借
    $('#simulate-scan').click(function() {
        if (!currentCabinet) {
            alert('未选择柜机');
            return;
        }

        // 找到所有可用槽位
        const availableSlots = $('.slot.available');
        if (availableSlots.length === 0) {
            alert('当前没有可用槽位');
            return;
        }

        // 随机选择一个
        const randomIndex = Math.floor(Math.random() * availableSlots.length);
        const slotDiv = $(availableSlots[randomIndex]);
        const slotNo = slotDiv.data('slot');

        // 调用 toggleSlot 模拟租借
        console.log(`模拟租借槽位${slotNo}, 槽位状态为1`);
        toggleSlot(slotNo, '1'); // '1' 表示当前将状态改为1，即已租借
    });

    function updateQRCode() {
        if (!currentCabinet || !currentCabinet.slots) return;

        // 获取所有可用槽位
        const availableSlots = currentCabinet.slots
            .filter(s => s.status === '0' || s.status === 'available')
            .map(s => s.slotNo || s.id); // 只保留槽位编号

        if (availableSlots.length === 0) {
            $('#device-qr').attr('src', '');
            return;
        }

        // 生成二维码内容，包含柜机ID和所有可用槽位
        const qrContent = JSON.stringify({
            cabinetId: currentCabinet.id,
            availableSlots: availableSlots
        });

        // 生成二维码并显示
        QRCode.toDataURL(qrContent, { width: 150, margin: 2 }, function(err, url) {
            if (!err) {
                $('#device-qr').attr('src', url);
            }
        });
    }



    /** 工具函数 */
    function logMessage(msg) {
        const now = new Date().toLocaleTimeString();
        $('#content').val($('#content').val() + `[${now}] ${msg}\n`);
        $('#content').scrollTop($('#content')[0].scrollHeight);
    }

    function updateTime() {
        $('#current-time').text(new Date().toLocaleString());
    }
    setInterval(updateTime, 1000);
    updateTime();

    initDeviceSelector();
});
</script>
</body>
</html>
